package org.ddpush.im.v1.node.udpconnector;

import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;

import org.ddpush.im.util.PropertyUtil;
import org.ddpush.im.v1.node.ClientMessage;
import org.ddpush.im.v1.node.ServerMessage;

/**
 * UDP服务器主类
 * 
 * @author lilei
 *
 */
public class UdpConnector {

	/**
	 * UDP服务器Cannel
	 */
	protected DatagramChannel antenna;// 天线

	/**
	 * //UDP消息接收处理类
	 * 
	 */
	protected Receiver receiver;
	/**
	 * UDP消息发送处理类
	 */
	protected Sender sender;

	/**
	 * UDP消息接受处理线程
	 * 
	 */
	protected Thread receiverThread;
	/**
	 * UDP消息发送处理线程
	 */
	protected Thread senderThread;

	/**
	 * 服务器启动标识
	 */
	boolean started = false;
	/**
	 * 服务器关闭标识
	 */
	boolean stoped = false;

	/**
	 * UDP端口号
	 * 
	 */
	protected int port = PropertyUtil.getPropertyInt("CLIENT_UDP_PORT");

	/**
	 * 设置端口
	 * 
	 * @param port
	 */
	public void setPort(int port) {
		this.port = port;
	}

	/**
	 * 获取端口
	 * 
	 * @return
	 */
	public int getPort() {
		return this.port;
	}

	public void init() {

	}

	/**
	 * 启动UDP服务器
	 * 
	 * @throws Exception
	 */
	public void start() throws Exception {
		// UDP服务器cannel 在启动之前不能被创建
		if (antenna != null) {
			throw new Exception("antenna is not null, may have run before");
		}
		// 打开UDP通道
		antenna = DatagramChannel.open();
		// 绑定端口
		antenna.socket().bind(new InetSocketAddress(port));
		System.out.println("udp connector port:" + port);
		// non-blocking
		// 设置为非阻塞模式
		antenna.configureBlocking(false);
		// 设置UDP服务器最大接受的数据包大小
		antenna.socket().setReceiveBufferSize(1024 * 1024 * PropertyUtil.getPropertyInt("CLIENT_UDP_BUFFER_RECEIVE"));
		// 设置UDP服务器最大发送数据包大小
		antenna.socket().setSendBufferSize(1024 * 1024 * PropertyUtil.getPropertyInt("CLIENT_UDP_BUFFER_SEND"));
		System.out.println("udp connector recv buffer size:" + antenna.socket().getReceiveBufferSize());
		System.out.println("udp connector send buffer size:" + antenna.socket().getSendBufferSize());

		// 创建UDP消息接受对象 并初始化
		this.receiver = new Receiver(antenna);
		this.receiver.init();
		// 创建UDP消息发送对象 并初始化
		this.sender = new Sender(antenna);
		this.sender.init();
		// 用UDP发射器以及接收器对象 创建相应的线程 并启动
		this.senderThread = new Thread(sender, "AsynUdpConnector-sender");
		this.receiverThread = new Thread(receiver, "AsynUdpConnector-receiver");
		this.receiverThread.start();
		this.senderThread.start();
	}

	/**
	 * 停止UDP服务器
	 * 
	 * @throws Exception
	 */
	public void stop() throws Exception {
		// 关闭 UDP 消息接受线程
		receiver.stop();
		// 关闭UDP 消息发送线程
		sender.stop();
		try {
			// 让UDP消息接受线程和发送线程完成收尾工作
			receiverThread.join();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			senderThread.join();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 关闭UDP服务器连接
		try {
			antenna.socket().close();
		} catch (Exception e) {
		}
		try {
			antenna.close();
		} catch (Exception e) {
		}
	}

	/**
	 * 获取 收到了多少个UDP数据包
	 * 
	 * @return
	 */
	public long getInqueueIn() {
		return this.receiver.queueIn.longValue();
	}

	/**
	 * 获取 取出了多少个收到的UDP消息包
	 * 
	 * @return
	 */
	public long getInqueueOut() {
		return this.receiver.queueOut.longValue();
	}

	/**
	 * 获取 要发送的消息个数
	 * 
	 * @return
	 */
	public long getOutqueueIn() {
		return this.sender.queueIn.longValue();
	}

	/**
	 * 获取 已经处理的 需要发送的消息个数
	 * 
	 * @return
	 */
	public long getOutqueueOut() {
		return this.sender.queueOut.longValue();
	}

	/**
	 * 获取一个客户端发过来的消息
	 * 
	 * @return
	 * @throws Exception
	 */
	public ClientMessage receive() throws Exception {
		// 调用 UDP消息接受处理类 的 receive() 函数 获取一个客户端消息
		return receiver.receive();
	}

	/**
	 * 发送一个UDP消息给客户端
	 * 
	 * @param message
	 * @return
	 * @throws Exception
	 */
	public boolean send(ServerMessage message) throws Exception {
		// 调用 UDP消息发射器类的send() 函数 发射一个UDP消息
		return sender.send(message);

	}

}
